
Texture2D cookieTexture;
sampler2D cookieSampler = sampler_state
{
	texture= cookieTexture;
	Filter = MIN_MAG_MIP_LINEAR;
	AddressU = WRAP;
	AddressV = WRAP;
};


struct tPerlinNoise
{
	float threshold;
	float amplitude;
	float frequency;
	int octaves;
	int type;
	int dimensions;
};

#ifdef D3D9_IMPL

float4x4 ViewProj;
float4x4 world;
tPerlinNoise noiseParam;

#else

cbuffer cbPerFrame {
	float4x4 ViewProj;
	float4x4 world;
};

cbuffer cbPerInit {
	tPerlinNoise noiseParam;
};

#endif


#define BASE_DIM_FLOAT 8.0f
#define INV_BASE_DIM (1.0f / BASE_DIM_FLOAT)
#define QUATER (0.25f) //(0.5f + 0.5f * 0.5f)
#define HALF_PLUS_QUATER (0.75f) //(0.5f + QUATER )

float2 BaseData2D(float x, float y)
{
//return float2(0,0);
	return ((tex2D(cookieSampler, float2(x,y)) - 0.5) * 2)* BASE_DIM_FLOAT;
	
}

float2 GridDir2D(float x, float y, float2 texCoord)
{
	return float2(texCoord.x - x, texCoord.y - y) * BASE_DIM_FLOAT;
}

float2 Curve(float2 t)
{
	return (float2(3,3) - float2(2,2) * t) * t * t;
}

float4 Noise2D(float2 uvCoord)
{
	float2 ScaledCoord = uvCoord * BASE_DIM_FLOAT;
	float2 GridFrac = frac(ScaledCoord);
	
	float2 grid_TL = (floor(ScaledCoord)) / BASE_DIM_FLOAT;
	float2 grid_BR = grid_TL + INV_BASE_DIM;
	
	float amp = noiseParam.amplitude;
		
	float tlDot = dot(BaseData2D(grid_TL.x, grid_TL.y), GridDir2D(grid_TL.x, grid_TL.y, uvCoord));
	float blDot = dot(BaseData2D(grid_TL.x, grid_BR.y), GridDir2D(grid_TL.x, grid_BR.y, uvCoord));
	float trDot = dot(BaseData2D(grid_BR.x, grid_TL.y), GridDir2D(grid_BR.x, grid_TL.y, uvCoord));
	float brDot = dot(BaseData2D(grid_BR.x, grid_BR.y), GridDir2D(grid_BR.x, grid_BR.y, uvCoord));
	
	float2 CurveWeights = Curve(GridFrac);
		
	float final = lerp(
		lerp(tlDot, trDot, CurveWeights.x), 
		lerp(blDot, brDot, CurveWeights.x), 
		CurveWeights.y);
	
	final =  (final + 0.5) / 2.0f;
	final *= amp;
	final += noiseParam.threshold;
	return final;
}



void myvs(
    float3 position	: POSITION,
	float3 normal : NORMAL,
	float2 uv_0 : TEXCOORD0,
	
#ifdef D3D9_IMPL 
	out float4 out_hposition : POSITION,
#else
	out float4 out_hposition : SV_Position,
#endif
	out float3 out_normal : TEXCOORD3,
	out float2 out_uv_0 : TEXCOORD0,
	out float2 out_uv_1 : TEXCOORD1,
	out float2 out_uv_2 : TEXCOORD2)
{
	out_hposition = mul( mul(world,ViewProj), float4(position, 1) );
	out_normal = mul(normal, (float3x3)world);
	//float2 uv_0 = (float2)0.0f;
	out_uv_0 = uv_0;
	out_uv_1 = uv_0;
	out_uv_2 = uv_0;
}

void myps(
#ifdef D3D9_IMPL 
    float4 position	: POSITION,
#else
    float4 position	: SV_Position,
#endif
	float3 normal : TEXCOORD3,
	float2 uv_0 : TEXCOORD0,
	float2 uv_1 : TEXCOORD1,
	float2 uv_2 : TEXCOORD2,
	
#ifdef D3D9_IMPL 
    out float4 out_color : COLOR
#else
    out float4 out_color : SV_Target
#endif
    )
{

	
	float octave = 1;
	out_color = Noise2D(uv_0 * noiseParam.frequency * octave) * (1.0f / octave);
	out_color.w = (1.0f / octave);
	
	//out_color = (float4)0;
}

#ifdef D3D9_IMPL

technique Technique0
{
    pass Pass0
    {
		SrcBlend = 5;
		DestBlend = 6;
		AlphaBlendEnable = TRUE;
		VertexShader = compile vs_2_0 myvs();
		PixelShader  = compile ps_2_0 myps();
    }
}

#else

technique10 Technique0
{
    pass Pass0
    {
        SetVertexShader( CompileShader( vs_4_0, myvs() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, myps() ) );
    }  
}

#endif